<?php
namespace Framework\SlickGrid;

/**
 * COLUMN DEFINITION (columns) OPTIONS:
 *     id                  - Column ID.
 *     name                - Column name to put in the header.
 *     toolTip             - Tooltip (if different from name).
 *     field               - Property of the data context to bind to.
 *     formatter           - (default 'return value || ""') Function responsible for rendering the contents of a cell. Signature: function formatter(row, cell, value, columnDef, dataContext) { ... return "..."; }
 *     editor              - An Editor class.
 *     validator           - An extra validation function to be passed to the editor.
 *     unselectable        - If true, the cell cannot be selected (and therefore edited).
 *     cannotTriggerInsert - If true, a new row cannot be created from just the value of this cell.
 *     width               - Width of the column in pixels.
 *     resizable           - (default true) If false, the column cannot be resized.
 *     sortable            - (default false) If true, the column can be sorted (onSort will be called).
 *     minWidth            - Minimum allowed column width for resizing.
 *     maxWidth            - Maximum allowed column width for resizing.
 *     cssClass            - A CSS class to add to the cell.
 *     rerenderOnResize    - Rerender the column when it is resized (useful for columns relying on cell width or adaptive formatters).
 *     asyncPostRender     - Function responsible for manipulating the cell DOM node after it has been rendered (called in the background).
 *     behavior            - Configures the column with one of several available predefined behaviors:  "select", "move", "selectAndMove".
 */
class ColumnCollection {
	
	protected $columns = array();
	protected $hiddenColumns = array();
	protected $prefix;
	protected $prefixUsed = false;
	
	public function __construct($prefix) {
		$this->prefix = $prefix;
	}
	
	public function addColumn($id, $name, $options=array()) {
		// Could have just passed everything through options, but I wanted to make it obvious 
		// which fields are required by passing them separately, without default values
		$newColumn = array_merge(array('id'=>$id, 'name'=>$name, 'field'=>$id), $options);
		$this->columns[$id] = $newColumn;
	}
	
	public function getColumns() {
		return $this->columns;
	}
	
	public function getHiddenColumns() {
		return $this->hiddenColumns;
	}

	/**
	 * addHiddenColumn adds a column that won't be displayed in the grid, but is present in the data.
	 * This is mostly useful for id fields.
	 */
	public function addHiddenColumn($field, $getter) {
		$this->hiddenColumns[$field] = $getter;
	}
	
	public function render($returnObj=false) {
		$columns = array_values($this->columns);
		if($returnObj) {
			return $columns;
		}
		else {
			return json_encode($columns);
		}
	}
	
	public function merge(ColumnCollection $other) {
		// Add a prefix to this column collection, if needed
		if(!$this->prefixUsed) {
			$newColumns = array();
			foreach($this->columns as $id => $def) {
				$def['id'] = $prefix.$id;
				$newColumns[$prefix.$id] = $def;
			}
			$this->columns = $newColumns;
			
			$newColumns = array();
			foreach($this->hiddenColumns as $id => $def) {
				$newColumns[$prefix.$id] = $def;
			}
			$this->hiddenColumns = $newColumns;
			
			$this->prefixUsed = true;
		}
		
		// Add a prefix to the other collection, if needed
		if(!$other->prefixUsed) {
			$newColumns = array();
			foreach($other->columns as $id => $def) {
				$def['id'] = $prefix.$id;
				$newColumns[$prefix.$id] = $def;
			}
			$other->columns = $newColumns;
			
			$newColumns = array();
			foreach($other->hiddenColumns as $id => $def) {
				$newColumns[$prefix.$id] = $def;
			}
			$other->hiddenColumns = $newColumns;
			
			$other->prefixUsed = true;
		}
		
		// merge the collections
		$this->columns = array_merge($this->columns, $other->columns);
		
	}
}